package thread;

import lombok.extern.slf4j.Slf4j;

import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;

/**
 * 线程不安全类的设计。【SimpleDateFormatTest】。
 * 这个类会出现线程安全问题。
 * 多线程访问这个类【出现了 NumberFormatException】异常。
 */
@Slf4j
public class SimpleDateFormatTest {


    public static void main(String[] args) {
        test1();
        test2();
    }


    /**
     * 有线程安全的问题。
     * @param args
     */
    public static void main1(String[] args) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        for (int i = 0; i < 10; i++) {
            new Thread(() -> {
                try {
                    log.debug("{}", sdf.parse("1951-04-21"));
                } catch (Exception e) {
                    log.error("{}", e);
                }
            }).start();
        }
    }

    /**
     * 解决方案1：使用【synchronized】。
     */
    private static void test1(){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

        for (int i = 0; i < 50; i++) {
            new Thread(() -> {
                synchronized (sdf) {
                    try {
                        log.debug("{}", sdf.parse("1951-04-21"));
                    } catch (Exception e) {
                        log.error("{}", e);
                    }
                }
            }).start();
        }
    }


    /**
     * 解决方案2：使用不可变类【DateTimeFormatter】
     */
    private static void test2(){
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd");

        for (int i = 0; i < 10; i++) {
            new Thread(() -> {
                LocalDate date = dtf.parse("2018-10-01", LocalDate::from);
                log.debug("{}", date);
            }).start();
        }
    }
}
